package stream.parallel;

import org.testng.Assert;
import org.testng.annotations.Test;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;

public class ParallelUnsafe {

    /**
     * 验证并行流线程不安全
     */
    @Test
    public void t1() {
        int size = 1000000;
        List<Integer> integers = new ArrayList<>();
        for (int i = 0; i < size; i++) {
            integers.add(1);
        }

        var map = new HashMap<Integer, Integer>();

        map.put(0, 0);
        var map2 = new ConcurrentHashMap<Integer, Integer>();
        map2.put(0, 0);
        // 和不等于size
        integers.parallelStream().forEach(i -> map.compute(0, (key, val) -> val + i));

        System.out.println(map.get(0));
        Assert.assertEquals(size, (int) map.get(0));
    }

    @Test
    public void t2() {
        int size = 1000000;
        List<Integer> integers = new ArrayList<>();
        for (int i = 0; i < size; i++) {
            integers.add(1);
        }

        var map = new ConcurrentHashMap<Integer, Integer>();
        map.put(0, 0);
        // 和不等于size
        integers.parallelStream().forEach(i -> map.compute(0, (key, val) -> val + i));

        System.out.println(map.get(0));
        Assert.assertEquals(size, (int) map.get(0));
    }

    /**
     * 偶尔会出现问题
     * Index 1239992 out of bounds for length 810325
     */
    @Test
    public void t3() {
        List<Integer> integers = new ArrayList<>();
        for (int i = 0; i < 10000000; i++) {
            integers.add(i);
        }
        System.out.println(integers.size());

        //通过并行流将List中的数据转存到另一个List集合中
        List<Integer> another = new CopyOnWriteArrayList<>();
        integers.parallelStream().forEach(another::add);
        System.out.println(another.size());
    }


}
